package com.iplay.service.favourites;

import java.util.Arrays;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mapping.PropertyReferenceException;
import org.springframework.stereotype.Service;

import com.iplay.dao.favourites.UserFavouritesDAO;
import com.iplay.dto.hotel.SimplifiedHotelDTO;
import com.iplay.entity.favourites.FavouritesTargetType;
import com.iplay.entity.favourites.UserFavouritesDO;
import com.iplay.service.exception.InvalidRequestParametersException;
import com.iplay.service.exception.ResourceForbiddenException;
import com.iplay.service.hotel.HotelService;
import com.iplay.service.user.UserServiceImpl;
import com.iplay.vo.favourites.PostFavouritesVO;

@Service
public class UserFavouritesServiceImpl implements UserFavouritesService {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);
	
	@Autowired
	private UserFavouritesDAO userFavouritesDAO;

	@Autowired
	private HotelService hotelService;

	@Override
	public Page<UserFavouritesDO> findFavouritesByUserId(int userId, Pageable pageable) {
		try {
			return userFavouritesDAO.findByUserId(userId, pageable);
		} catch (PropertyReferenceException e) {
			throw new InvalidRequestParametersException(e.getMessage());
		}
	}

	@Override
	public List<SimplifiedHotelDTO> findFavouriteHotelsByUserId(int userId, Pageable pageable) {
		Page<Integer> hotelIds = findFavouritesByUserId(userId, pageable).map(UserFavouritesDO::getTargetId);
		return hotelService.listHotelsByIds(hotelIds.getContent());
	}

	@Override
	public boolean addFavourites(int userId, PostFavouritesVO vo) {
		if(userFavouritesDAO.findByUserIdAndTargetIdAndTargetType(userId, vo.getTargetId(),
				vo.getTargetType())!=null)
			throw new ResourceForbiddenException("User has already liked the "+vo.getTargetType().toString().toLowerCase()+"!");
		try{
			userFavouritesDAO
			.save(new UserFavouritesDO(userId, vo.getTargetId(), vo.getTargetType(), System.currentTimeMillis()));
		}catch(DataIntegrityViolationException e){
			LOGGER.error(e.getMessage(), e);
		}
		return true;
	}

	@Override
	public SimplifiedHotelDTO findFavouriteHotelByUserIdAndHotelId(int userId, int hotelId) {
		UserFavouritesDO userFavouritesDO = userFavouritesDAO.findByUserIdAndTargetIdAndTargetType(userId, hotelId,
				FavouritesTargetType.HOTEL);
		if (userFavouritesDO == null)
			return null;
		List<SimplifiedHotelDTO> rs = hotelService.listHotelsByIds(Arrays.asList(userFavouritesDO.getTargetId()));
		return rs.isEmpty() ? null : rs.get(0);
	}

	@Override
	public boolean deleteFavourites(int userId, PostFavouritesVO vo) {
		userFavouritesDAO.deleteByUserIdAndTargetIdAndTargetType(userId, vo.getTargetId(), vo.getTargetType());
		return true;
	}

}
